import apis from '@/apis/hikivision-video.js';

export default {
  emits: ['changeVisible'],
  data() {
    return {
      domId: '',
      oWebControl: null,
      initCount: 0,
      pubKey: '',
      msg: '',
      isShowPreviewVideoTip: false,
    };
  },
  watch: {
    w() {
      setTimeout(()=>{
        this.resizeVideoWin();
      }, 1565);
    },
    h() {
      setTimeout(() => {
        this.resizeVideoWin();
      }, 1565);
    },
    x() {
      setTimeout(() => {
        this.resizeVideoWin();
      }, 1565);
    },
    y() {
      setTimeout(() => {
        this.resizeVideoWin();
      }, 1565);
    },
  },
  methods: {
    initPlugin() {
      this.msg = '监控视频加载中，请稍候...';
      this.oWebControl = new WebControl({
        szPluginContainer: this.domId, // 指定容器id
        iServicePortStart: 15900, // 指定起止端口号，建议使用该值
        iServicePortEnd: 15909,
        szClassId: '23BF3B0A-2C56-4D97-9C03-0CB103AA8F11', // 用于IE10使用ActiveX的clsid
        cbConnectSuccess: () => {
          // 创建WebControl实例成功
          this.oWebControl
            .JS_StartService('window', {

              // WebControl实例创建成功后需要启动服务
              dllPath: './VideoPluginConnect.dll', // 值"./VideoPluginConnect.dll"写死
            })
            .then(
              () => {
                // 启动插件服务成功
                this.oWebControl.JS_SetWindowControlCallback({

                  // 设置消息回调
                  cbIntegrationCallBack: this.cbIntegrationCallBack,
                });

                this.oWebControl.JS_CreateWnd(this.domId, this.w, this.h).then(() => {
                  this.init(); // 创建播放实例成功后初始化
                });
              },
              () => {
                // 启动插件服务失败
              },
            );
        },
        cbConnectError: () => {
          // 创建WebControl实例失败
          this.oWebControl = null;
          this.msg = '插件未启动，正在尝试启动，请稍候...';
          WebControl.JS_WakeUp('VideoWebPlugin://'); // 程序未启动时执行error函数，采用wakeup来启动程序
          this.initCount++;
          if (this.initCount < 3) {
            setTimeout(() => {
              this.initPlugin();
            }, 2000);
          } else {
            this.msg = '插件启动失败，请检查插件是否安装!';
          }
        },
        cbConnectClose: bNormalClose => {
          if (!bNormalClose) {

          } else {

          }
          this.oWebControl = null;
        },
      });
    },

    // 设置窗口控制回调
    setCallbacks() {
      this.oWebControl.JS_SetWindowControlCallback({
        cbIntegrationCallBack: this.cbIntegrationCallBack,
      });
    },

    // 推送消息
    async cbIntegrationCallBack(oData) {
      if (oData.responseMsg && oData.responseMsg.msg && oData.responseMsg.msg.result === 768) {
        this.msg = '抓图失败,请重试!';
      }
      if (oData.responseMsg &&
        oData.responseMsg.msg &&
        oData.responseMsg.msg.result === 16 &&
        this.videLayout === '1x1'
      ) {
        this.$emit('changeVisible', false);
      }
    },
    async getHikivisionMonitorSourceInfo(sourceId) {
      const params = {
        sourceId,
      };

      try {
        const res = await apis.getHikivisionMonitorSourceInfo(params);

        if (res.data.code === 200) {
          const { host = '', appKey = '', appSecret = '' } = res.data.data || {};
          return {
            ip: host,
            appkey: appKey,
            secret: appSecret,
          };
        } else {
          this.$message({
            type: 'error',
            message: res.data.msg,
          });

          return null;
        }
      } catch (error) {
        this.$message({
          type: 'error',
          message: error,
        });

        return null;
      }
    },

    // 初始化
    init() {
      this.getPubKey(async() => {
        let { appkey } = this; // 综合安防管理平台提供的appkey，必填
        let { ip } = this; // 综合安防管理平台IP地址，必填
        let { secret } = this;

        // 如果视频源不存在表示是历史数据则密钥需要加密
        if (!this.sourceId) {
          secret = this.setEncrypt(this.secret);
        } else {
          // 获取appkey/ip/secret
          const sourceInfo = await this.getHikivisionMonitorSourceInfo(this.sourceId);

          if (sourceInfo) {
            ip = sourceInfo.ip;
            secret = this.setEncrypt(sourceInfo.secret);
            appkey = sourceInfo.appkey;
          }
        }

        const playMode = 0; // 初始播放模式：0-预览，1-回放
        const port = 443; // 综合安防管理平台端口，若启用HTTPS协议，默认443
        const { snapDir } = this; // 抓图存储路径
        const { videoDir } = this; // 紧急录像或录像剪辑存储路径
        const layout = this.videLayout; // playMode指定模式的布局 '1x1'
        const enableHTTPS = 1; // 是否启用HTTPS协议与综合安防管理平台交互，这里总是填1
        const encryptedFields = 'secret'; // 加密字段，默认加密领域为secret
        const showToolbar = 1; // 是否显示工具栏，0-不显示，非0-显示
        const showSmart = 1; // 是否显示智能信息（如配置移动侦测后画面上的线框），0-不显示，非0-显示
        const buttonIDs = '0,16,256,257,258,259,260,512,513,514,515,516,517,768,769'; // 自定义工具条按钮

        this.oWebControl
          .JS_RequestInterface({
            funcName: 'init',
            argument: JSON.stringify({
              appkey: appkey, // API网关提供的appkey
              secret: secret, // API网关提供的secret
              ip: ip, // API网关IP地址
              playMode: playMode, // 播放模式（决定显示预览还是回放界面）
              port: port, // 端口
              snapDir: snapDir, // 抓图存储路径
              videoDir: videoDir, // 紧急录像或录像剪辑存储路径
              layout: layout, // 布局
              enableHTTPS: enableHTTPS, // 是否启用HTTPS协议
              encryptedFields: encryptedFields, // 加密字段
              showToolbar: showToolbar, // 是否显示工具栏
              showSmart: showSmart, // 是否显示智能信息
              buttonIDs: buttonIDs, // 自定义工具条按钮
            }),
          })
          .then(oData => {
            let visualModule = {
              rateW: 1,
            };
            if (process.env.NODE_ENV === 'production') {
              visualModule = window._xvueStore.state.VisualComponentsModule;
            }
            const { rateW } = visualModule;
            this.msg = '';
            if (this.displayStyle === 'icon' && (this.isInDialog !== '1')) {
              this.oWebControl.JS_Resize(this.w, this.h);
            } else {
              // 在弹框里不需要随页面缩放
              if (this.isInDialog === '1') {
                this.oWebControl.JS_Resize(this.w, this.h);
              } else {
                this.oWebControl.JS_Resize(this.w * rateW, this.h); // 初始化后resize一次，规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
              }
            }
            setTimeout(() => {
              this.startPreview();
            }, 0);
          });
      });
    },

    // 获取公钥
    getPubKey(callback) {
      this.oWebControl
        .JS_RequestInterface({
          funcName: 'getRSAPubKey',
          argument: JSON.stringify({
            keyLength: 1024,
          }),
        })
        .then(oData => {
          if (oData.responseMsg.data) {
            this.pubKey = oData.responseMsg.data;
            callback();
          }
        });
    },

    // RSA加密
    setEncrypt(value) {
      const encrypt = new JSEncrypt();
      encrypt.setPublicKey(this.pubKey);
      return encrypt.encrypt(value);
    },

    // 监听resize事件，使插件窗口尺寸跟随DIV窗口变化
    resizeVideoWin() {
      if (this.oWebControl) {
        let visualModule = {
          rateW: 1,
        };
        if (process.env.NODE_ENV === 'production') {
          visualModule = window._xvueStore.state.VisualComponentsModule;
        }

        if (this.isInDialog === '1') {
          this.oWebControl.JS_Resize(this.w, this.h);
        } else {
          const { rateW } = visualModule;
          this.oWebControl.JS_Resize(this.w * rateW, this.h);
        }

        this.setWndCover();
      }
    },

    // 设置窗口裁剪，当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
    setWndCover() {
      const iWidth = document.body.clientWidth;
      const iHeight = document.body.clientHeight;
      const oDivRect = document.getElementById(this.domId).getBoundingClientRect();

      let iCoverLeft = oDivRect.left < 0 ? Math.abs(oDivRect.left) : 0;
      let iCoverTop = oDivRect.top < 0 ? Math.abs(oDivRect.top) : 0;
      let iCoverRight = oDivRect.right - iWidth > 0 ? Math.round(oDivRect.right - iWidth) : 0;
      let iCoverBottom = oDivRect.bottom - iHeight > 0 ? Math.round(oDivRect.bottom - iHeight) : 0;

      iCoverLeft = iCoverLeft > this.w ? this.w : iCoverLeft;
      iCoverTop = iCoverTop > this.h ? this.h : iCoverTop;
      iCoverRight = iCoverRight > this.w ? this.w : iCoverRight;
      iCoverBottom = iCoverBottom > this.h ? this.h : iCoverBottom;

      this.oWebControl.JS_RepairPartWindow(0, 0, this.w + 1, this.h); // 多1个像素点防止还原后边界缺失一个像素条
      if (iCoverLeft !== 0) {
        this.oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, this.h);
      }
      if (iCoverTop !== 0) {
        this.oWebControl.JS_CuttingPartWindow(0, 0, this.w + 1, iCoverTop); // 多剪掉一个像素条，防止出现剪掉一部分窗口后出现一个像素条
      }
      if (iCoverRight !== 0) {
        this.oWebControl.JS_CuttingPartWindow(this.w - iCoverRight, 0, iCoverRight, this.h);
      }
      if (iCoverBottom !== 0) {
        this.oWebControl.JS_CuttingPartWindow(0, this.h - iCoverBottom, this.w, iCoverBottom);
      }
    },
    startPreview() {
      if (!this.isDesignView || (this.isDesignView && this.isMashupPreviewVideo)) {
        if (this.propCameraIndexCodes && this.propCameraIndexCodes.length > 1) {
          this.startMuiltyPreview();
        } else {
          this.startSinglePreview();
        }
      } else {
        this.isShowPreviewVideoTip = true;
        this.destroyedVideo();
      }
    },
    startSinglePreview() {
      const cameraIndexCode = this.cameraIndexCode.replace(/(^\s*)/g, '');
      if (cameraIndexCode) {
        const streamMode = 0; // 主子码流标识：0-主码流，1-子码流
        const transMode = 1; // 传输协议：0-UDP，1-TCP
        const gpuMode = 0; // 是否启用GPU硬解，0-不启用，1-启用
        const wndId = -1; // 播放窗口序号（在2x2以上布局下可指定播放窗口）
        this.oWebControl.JS_RequestInterface({
          funcName: 'startPreview',
          argument: JSON.stringify({
            cameraIndexCode, // 监控点编号
            streamMode: streamMode, // 主子码流标识
            transMode: transMode, // 传输协议
            gpuMode: gpuMode, // 是否开启GPU硬解
            wndId: wndId, // 可指定播放窗口
          }),
        });
      }
    },
    startMuiltyPreview() {
      const list = [];
      this.propCameraIndexCodes.forEach((item, index) => {
        const cameraIndexCode = item.replace(/(^\s*)/g, '');

        // 如果存在cameraIndexCode则预览
        if (cameraIndexCode) {
          list.push({
            authUuid: '',
            cameraIndexCode,
            ezvizDirect: 0,
            gpuMode: 0,
            streamMode: 0,
            transMode: 1,
            wndId: index + 1,
          });
        }
      });

      const argument = {
        list,
      };

      const requestInterface = {
        argument: JSON.stringify(argument),
        funcName: 'startMultiPreviewByCameraIndexCode',
      };
      this.oWebControl.JS_RequestInterface(requestInterface);
    },
    async destroyedVideo() {
      if (this.oWebControl) {
        this.oWebControl.JS_RequestInterface({
          funcName: 'stopAllPreview',
        });

        // 先让窗口隐藏，规避可能的插件窗口滞后于浏览器消失问题
        this.oWebControl.JS_HideWnd();

        await this.oWebControl.JS_DestroyWnd().then(
          ()=>{},
        );

        await this.oWebControl.JS_Disconnect().then(
          ()=>{},
        );
      }
    },
  },
  beforeUnmount() {
    this.destroyedVideo();
  },
};
